import xml.etree.ElementTree as ET
import os,time,threading
import myFtp
import shutil

class PCheckItem:
	def __init__(self):
		self.m_dir=""
		self.m_subdir=""
		self.m_file=""

class PDirCheckMonitor:
	def __init__(self):
		self.m_strDir = ""
		self.m_dictFileInfo = {}
		return

	def __del__(self):
		return

	def startMonitor(self,strDir):
		self.m_strDir = strDir
		for (dirname, subdir, subfile) in os.walk(self.m_strDir):
			for f in subfile:
				self.m_dictFileInfo[os.path.join(dirname, f)] = os.path.getmtime(os.path.join(dirname, f))

	def getModifyFileList(self):
		retFileList = []
		for (dirname, subdir, subfile) in os.walk(self.m_strDir):
			for f in subfile:
				if self.m_dictFileInfo.has_key(os.path.join(dirname, f)):
					if self.m_dictFileInfo[os.path.join(dirname, f)] != os.path.getmtime(os.path.join(dirname, f)):
						self.m_dictFileInfo[os.path.join(dirname, f)] = os.path.getmtime(os.path.join(dirname, f))
						fileitem = PCheckItem()
						fileitem.m_dir = dirname
						fileitem.m_subdir = dirname.replace(self.m_strDir,'')
						fileitem.m_file = f
						retFileList.append(fileitem)
				else:
					self.m_dictFileInfo[os.path.join(dirname, f)] = os.path.getmtime(os.path.join(dirname, f))
		return retFileList

class PCheckOneCfg:
	def __init__(self):
		self.m_name=""
		self.m_desttype=""
		self.m_notifydir=""
		self.m_todir=""
		self.m_ip=""
		self.m_user=""
		self.m_passwd=""

	def dump(self):
		print "check %s at : "%(self.m_name)
		print "  check dir : "+self.m_notifydir
		print "  to dir    : "+self.m_todir
		print "  dest type : "+self.m_desttype
		print "  to ip     : "+self.m_ip
		print "  user      : "+self.m_user
		print "  passwd    : "+self.m_passwd

class PCheckCfgs:
	def __init__(self,cfgfile):
		self.m_cfg=cfgfile
		self.m_checklist=[]

	def parseCfg(self):
		ettree = ET.ElementTree()
		ettree.parse(self.m_cfg)
		root=ettree.getroot() 
		for checkitem in root.findall("checkitem"):
			onecheckcfg = PCheckOneCfg()
			onecheckcfg.m_name = checkitem.find("notifyname").text
			onecheckcfg.m_notifydir = checkitem.find("notifydir").text
			onecheckcfg.m_todir = checkitem.find("todir").text
			onecheckcfg.m_desttype = checkitem.find("desttype").text
			onecheckcfg.m_ip = checkitem.find("ip").text
			onecheckcfg.m_user = checkitem.find("user").text
			onecheckcfg.m_passwd = checkitem.find("passwd").text
			self.m_checklist.append(onecheckcfg)

	def getChecklist(self):
		return self.m_checklist	

class PCopyer:
    def __init__(self,onecheckcfg):
        self.m_cfg = onecheckcfg
        
    def copy(src,dest):
        print "i am a base copyer from %s to %s"%(src,dest)
        
class PFtpCopyer(PCopyer):
    def __init__(self,onecheckcfg):
        PCopyer.__init__(self,onecheckcfg)
        self.m_ftp = myFtp.myFTP(self.m_cfg.m_ip,self.m_cfg.m_user,self.m_cfg.m_passwd)
        
    def copy(self,src,dest):
        self.m_ftp.putFile(fromfile,tofile)
        
class PLocalCopyer(PCopyer):
    def __init__(self,onecheckcfg):
        PCopyer.__init__(self,onecheckcfg)
        
    def copy(self,src,dest):
        shutil.copy(src,dest)
        
class POneChecker:
	def __init__(self,onecheckcfg):
		self.m_cfg = onecheckcfg
		self.m_monitor = PDirCheckMonitor()
		self.m_monitor.startMonitor(onecheckcfg.m_notifydir)
		if self.m_cfg.m_desttype == "ftp":
			self.m_copy = PFtpCopyer(onecheckcfg)
		else:
			self.m_copy = PLocalCopyer(onecheckcfg)
		
	def doRefresh(self):
		fileitemlist = self.m_monitor.getModifyFileList()
		for onefileitem in fileitemlist:
			fromfile = os.path.join(onefileitem.m_dir, onefileitem.m_file)
			tofile = ""
			if self.m_cfg.m_desttype == "ftp":
				tofile = self.m_cfg.m_todir + onefileitem.m_subdir.replace("\\","/") + '/' + onefileitem.m_file
			else:
				tofile = os.path.join(os.path.join(self.m_cfg.m_todir ,onefileitem.m_subdir),onefileitem.m_file)
			print "[%s][%s] %s changed"%(self.m_cfg.m_name,time.asctime(time.localtime()),fromfile)
			self.m_copy.copy(fromfile,tofile)
			print "[%s][%s] %s updated"%(self.m_cfg.m_name,time.asctime(time.localtime()),tofile)

def oneThreadWorker(onecheck):
	while True:
		onecheck.doRefresh()
		time.sleep(1)

if __name__ == '__main__':
	checkers = []

	checkCfgs = PCheckCfgs("cfg.xml")
	checkCfgs.parseCfg()
	checklist = checkCfgs.getChecklist()
	for onecheckcfg in checklist:
		onecheckcfg.dump()
		onecheck = POneChecker(onecheckcfg)
		checkers.append(onecheck)

	print "all works started.\n"
		
	workThreads=[]
	for onecheck in checkers:
		t = threading.Thread(target=oneThreadWorker, args=(onecheck,))
		workThreads.append(t)

	for oneThread in workThreads:
		oneThread.start()

	for oneThread in workThreads:
		oneThread.join()
